﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ESGenerator
{
    public class MapperGenerator
    {
        public static string PerformClass(Type typeEntity, string nameSpace) {
            string chaine = PerformImports();

            // Namespace
            chaine += "\nnamespace " + nameSpace + "\n";
            chaine += "{\n";

            // La classe
            chaine += "public class " + typeEntity.Name + "Mappeur : IMappeur<" + typeEntity.Name + "," + typeEntity.Name + "ES>\n";
            chaine += "{\n";
            chaine += "public " + typeEntity.Name + "Mappeur() {}\n";

            // Méthode Entity2ES
            //public StagiaireES Entity2ES(Stagiaire entity)
            chaine += "public " + typeEntity.Name + "ES Entity2ES(" + typeEntity.Name + " entity) {\n";
            chaine += typeEntity.Name+"ES retour = new "+typeEntity.Name+"ES();\n";
            // Les proprietes
            foreach (PropertyInfo property in typeEntity.GetProperties())
            {
                // On ignore les types spécifiques aux entities
                if (property.PropertyType.ToString().Contains("EntityReference") ||
                    property.PropertyType.ToString().Contains("EntityState") ||
                    property.PropertyType.ToString().Contains("EntityKey"))
                {
                    continue;
                }

                chaine += PerformProperty(property, true);
            }
            chaine += "return retour;\n}\n";

            // Méthode ES2Entity
            chaine += "public " + typeEntity.Name + " ES2Entity(" + typeEntity.Name + "ES es) {\n";
            chaine += typeEntity.Name + " retour = new " + typeEntity.Name + "();\n";
            // Les proprietes
            foreach (PropertyInfo property in typeEntity.GetProperties())
            {
                // On ignore les types spécifiques aux entities
                if (property.PropertyType.ToString().Contains("EntityReference") ||
                    property.PropertyType.ToString().Contains("EntityState") ||
                    property.PropertyType.ToString().Contains("EntityKey"))
                {
                    continue;
                }
                chaine += PerformProperty(property, false);
            }
            chaine += "return retour;\n}\n";

            // Fin de fichier
            chaine += "}\n}";

            return chaine;
        }

        private static string PerformImports() {
            // Les imports
            string chaine = "using System;\n"
               + "using System.Collections.Generic;\n"
               + "using System.Text;\n"
               + "using GestionPedago.EntityContext;\n"
               + "using GestionPedago.Services.Framework;\n"
               + "using GestionPedago.Services.Commun.ES;\n";
            return chaine;
        }

        private static string PerformProperty(PropertyInfo property, bool direction) {
            string chaine = "";
     
            if (property.PropertyType.ToString().Contains("EntityContext"))
            {
                chaine += "//TODO implémenter mapping Entity<->ES manuellement ! : "+property.Name + "\n";
            } else if (property.PropertyType.ToString().Contains("EntityCollection")) {
                chaine += "//TODO implémenter mapping collections manuellement ! : " + property.Name + "\n";
            } else if (direction)
            {
                chaine += "retour." + property.Name + " = entity." + property.Name + ";\n";
            }
            else
            {
                chaine += "retour." + property.Name + " = es." + property.Name + ";\n";
            }
            return chaine;
        }
    }
}
